package cn.gztang.controller;

import cn.gztang.constant.ErrorCode;
import cn.gztang.constant.UserType;
import cn.gztang.entity.dto.ResultBean;
import cn.gztang.entity.dto.UserInfoAdd;
import cn.gztang.entity.dto.UserInfoUpdate;
import cn.gztang.entity.dto.UserPasswordUpdate;
import cn.gztang.entity.po.UserInfo;
import cn.gztang.entity.qo.UserLoginQuery;
import cn.gztang.entity.vo.UserInfoVO;
import cn.gztang.exception.InvalidRequestParamException;
import cn.gztang.service.UserService;
import cn.gztang.util.StringUtil;
import cn.gztang.util.ValidateUtil;
import org.dozer.Mapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;

import static cn.gztang.constant.UserType.*;

/**
 * @author GaoFeng2017
 * @date 2018/9/9 18:34
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private Mapper mapper;

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @PostMapping("/login")
    @ResponseBody
    public Object userLogin(HttpSession session, @RequestBody @Validated UserLoginQuery loginQuery, BindingResult result) {

        ValidateUtil.checkRequestParam(result);

        String account = loginQuery.getAccount();
        String password = loginQuery.getPassword();

        UserInfo userInfo = userService.findByPassword(account, password);

        if (ValidateUtil.isNull(userInfo)) {
            return new ResultBean<>(false,ErrorCode.DATA_NOT_FOUND,"用户账号或密码错误");
        }

        session.setAttribute(LOGIN_INFO,mapper.map(userInfo,UserInfoVO.class));

        return new ResultBean<>();
    }

    @RequestMapping("/login/info")
    @ResponseBody
    public Object getUserInfo(HttpSession session) {

        UserInfoVO userInfoVO = (UserInfoVO) session.getAttribute(LOGIN_INFO);

        if (userInfoVO == null) {
            return new ResultBean<>(false,ErrorCode.DATA_NOT_FOUND,"用户未登录");
        }

        return new ResultBean<>(userInfoVO);
    }

    @RequestMapping("/add")
    @ResponseBody
    public Object addUser(HttpSession session, @RequestBody @Validated UserInfoAdd infoAdd, BindingResult result) {
        ValidateUtil.checkRequestParam(result);

        // 验证权限
        UserInfoVO userInfoVO = (UserInfoVO) session.getAttribute(LOGIN_INFO);
        Byte type = userInfoVO.getType();
        ValidateUtil.checkAccess(type,SUPER_ADMIN_TYPE,ADMIN_TYPE);

        if (infoAdd.getType() == ADMIN_TYPE && type != SUPER_ADMIN_TYPE) {
            throw new InvalidRequestParamException("权限不足,访问失败",ErrorCode.TYPE_MISMATCHING);
        }

        UserInfo userInfo = mapper.map(infoAdd, UserInfo.class);
        userInfo.setGmtCreate(new Date());
        userInfo.setPassword(StringUtil.getMD5(userInfo.getPassword()));
        Integer addCount = userService.addUserInfo(userInfo);
        return new ResultBean<>(addCount);
    }

    @RequestMapping("/password/update")
    @ResponseBody
    public Object updatePassword(HttpSession session, @RequestBody @Validated UserPasswordUpdate passwordUpdate, BindingResult result) {

        ValidateUtil.checkRequestParam(result);

        // 验证权限
        UserInfoVO userInfoVO = (UserInfoVO) session.getAttribute(LOGIN_INFO);
        Byte voType = userInfoVO.getType();
        ValidateUtil.checkAccess(voType,SUPER_ADMIN_TYPE, ADMIN_TYPE);

        UserInfo userInfo = userService.findByAccount(passwordUpdate.getAccount());
        String oldPassword = StringUtil.getMD5(passwordUpdate.getOldPassword());
        String newPassword = StringUtil.getMD5(passwordUpdate.getNewPassword());

        Byte type = userInfo.getType();

        if (type == SUPER_ADMIN_TYPE && voType != SUPER_ADMIN_TYPE) {
            throw new InvalidRequestParamException("权限不足,访问失败",ErrorCode.TYPE_MISMATCHING);
        }

        int updateCount = 0;
        if (Objects.equals(oldPassword,userInfo.getPassword())) {
            UserInfo updateInfo = new UserInfo();
            updateInfo.setId(userInfo.getId());
            updateInfo.setPassword(newPassword);
            updateCount = userService.updateUserInfo(updateInfo);
        }


        return new ResultBean<>(updateCount);
    }

    @RequestMapping("info/update")
    @ResponseBody
    public Object updateUser(HttpSession session, @RequestBody @Validated UserInfoUpdate infoUpdate, BindingResult result) {

        ValidateUtil.checkRequestParam(result);

        // 验证权限
        UserInfoVO userInfoVO = (UserInfoVO) session.getAttribute(LOGIN_INFO);
        ValidateUtil.checkAccess(userInfoVO.getType(),SUPER_ADMIN_TYPE);

        UserInfo userInfo = mapper.map(infoUpdate, UserInfo.class);

        Integer updateCount = userService.updateUserInfo(userInfo);

        return new ResultBean<>(updateCount);
    }

    @RequestMapping("/logout")
    @ResponseBody
    public Object logout(HttpSession session) {
        session.removeAttribute(LOGIN_INFO);
        return new ResultBean<>();
    }

    @RequestMapping("/all/list")
    @ResponseBody
    public Object selectAllUser(HttpSession session) {

        // 验证权限
        UserInfoVO userInfoVO = (UserInfoVO) session.getAttribute(LOGIN_INFO);
        Byte type = userInfoVO.getType();
        ValidateUtil.checkAccess(type,SUPER_ADMIN_TYPE,ADMIN_TYPE);

        List<UserInfoVO> allUser = userService.findAllUser();

        ListIterator<UserInfoVO> userInfoVOListIterator = allUser.listIterator();

        if (Objects.equals(type, ADMIN_TYPE)) {
            while (userInfoVOListIterator.hasNext()) {
                UserInfoVO infoVO = userInfoVOListIterator.next();
                if (Objects.equals(infoVO.getType(),UserType.SUPER_ADMIN_TYPE)) {
                    userInfoVOListIterator.remove();
                }
            }
        }
        return new ResultBean<>(allUser);
    }
}
